#include "common_property.h"
#include <stdexcept>

namespace El {
namespace Common {

CommonProperty &CommonProperty::GetInstance()
{
    static CommonProperty instance;
    return instance;
}

void CommonProperty::RegisterCallback(const std::string &key, PropertyCallback callback)
{
    if (!callback) {
        return;
    }
    std::lock_guard<std::mutex> lock(mutex_);
    callbacks_[key] = std::move(callback);
}

void CommonProperty::UnregisterCallback(const std::string &key)
{
    std::lock_guard<std::mutex> lock(mutex_);
    callbacks_.erase(key);
}

void CommonProperty::SetProperty(const std::string &key, const std::string &value)
{
    std::lock_guard<std::mutex> lock(mutex_);
    properties_[key] = value;
}

std::string CommonProperty::GetProperty(const std::string &key, const std::string &defaultValue) const
{
    std::lock_guard<std::mutex> lock(mutex_);

    // 先查找是否有回调函数
    auto callbackIt = callbacks_.find(key);
    if (callbackIt != callbacks_.end()) {
        try {
            return callbackIt->second();
        } catch (const std::exception &) {
            // 回调函数执行失败，继续尝试从属性map中获取
        }
    }

    // 从属性map中获取
    auto it = properties_.find(key);
    return (it != properties_.end()) ? it->second : defaultValue;
}

void CommonProperty::SetProperty(const std::string &key, int32_t value)
{
    std::lock_guard<std::mutex> lock(mutex_);
    properties_[key] = std::to_string(value);
}

int32_t CommonProperty::GetProperty(const std::string &key, int32_t defaultValue) const
{
    try {
        return std::stoi(GetProperty(key, std::to_string(defaultValue)));
    } catch (const std::exception &) {
        return defaultValue;
    }
}

bool CommonProperty::HasProperty(const std::string &key) const
{
    std::lock_guard<std::mutex> lock(mutex_);
    return callbacks_.find(key) != callbacks_.end() || properties_.find(key) != properties_.end();
}

void CommonProperty::RemoveProperty(const std::string &key)
{
    std::lock_guard<std::mutex> lock(mutex_);
    properties_.erase(key);
    callbacks_.erase(key);
}

void CommonProperty::Clear()
{
    std::lock_guard<std::mutex> lock(mutex_);
    properties_.clear();
    callbacks_.clear();
}

} // namespace common
} // namespace El